package store.lunangangster.bpmn.util;

import java.util.Map;
import javax.xml.stream.Location;
import javax.xml.stream.XMLStreamReader;
import store.lunangangster.bpmn.converter.parser.BaseChildElementParser;
import store.lunangangster.bpmn.model.BaseElement;
import store.lunangangster.bpmn.model.BpmnModel;

public class BpmnXmlUtil {

  /**
   * 为指定元素添加其在Xml中的指定Location
   * @param xsr       xml输入流
   * @param element   bpmnElement
   */
  public static void addXmlLocation(XMLStreamReader xsr, BaseElement element) {
    Location location = xsr.getLocation();
    int rowNumber = location.getLineNumber();
    int columnNumber = location.getColumnNumber();
    element.setXmlRowNumber(rowNumber);
    element.setXmlColumnNumber(columnNumber);
  }

  /**
   * 解析指定parentElement中的所有子元素，不在指定解析器集合中的属性将无法被解析
   * <p>需要注意的是：当该方法执行完成之后，xsr对象将会读取完整个parentElement对象标签，并且即将
   * 读取下一个标签。
   *
   * @param xsr                   xml输入流
   * @param parentElement         父元素
   * @param parentName            父元素名
   * @param model                 当前BpmnModel对象
   * @param childElementParsers   解析器集合
   */
  public static void parseChildElement(
      XMLStreamReader xsr,
      BaseElement parentElement,
      String parentName,
      BpmnModel model,
      Map<String, BaseChildElementParser> childElementParsers) throws Exception {
    // 指示父元素是否解析结束
    boolean endOfParent = false;
    while (!endOfParent && xsr.hasNext()) {
      xsr.next();

      if (xsr.isStartElement()) {
        String localName = xsr.getLocalName();

        if (childElementParsers.containsKey(localName)) {
          BaseChildElementParser childParser = childElementParsers.get(localName);
          childParser.parseChild(xsr, parentElement, model);

        }
      } else if (xsr.isEndElement()) {
        String localName = xsr.getLocalName();
        if (parentName.equals(localName)) {
          // 为什么不直接return？
          // 因为这里需要让xsr流将整个parentElement标签读取完毕，使得xsr流下次
          // 读取时，会从下一个元素直接开始
          endOfParent = true;
        }
      }
    }
  }
}
